/*
* Main.java
* Copyright (C) 2003
*
* $Id: Main.java,v 1.7 2005/05/07 18:23:25 cawe Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
using System;
using Defines = Suake2.UI.Defines;
using Globals = Suake2.UI.Globals;
using VID = Suake2.UI.client.VID;
using entity_t = Suake2.UI.client.entity_t;
using particle_t = Suake2.UI.client.particle_t;
using refdef_t = Suake2.UI.client.refdef_t;
using Cmd = Suake2.UI.game.Cmd;
using cplane_t = Suake2.UI.game.cplane_t;
using cvar_t = Suake2.UI.game.cvar_t;
using Com = Suake2.UI.qcommon.Com;
using Cvar = Suake2.UI.qcommon.Cvar;
using qfiles = Suake2.UI.qcommon.qfiles;
using xcommand_t = Suake2.UI.qcommon.xcommand_t;
using glconfig_t = Suake2.UI.render.glconfig_t;
using glstate_t = Suake2.UI.render.glstate_t;
using image_t = Suake2.UI.render.image_t;
using mleaf_t = Suake2.UI.render.mleaf_t;
using model_t = Suake2.UI.render.model_t;
using Math3D = Suake2.UI.util.Math3D;
using Vargs = Suake2.UI.util.Vargs;
//UPGRADE_TODO: The type 'java.nio.FloatBuffer' could not be found. If it was not included in the conversion, there may be compiler issues. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1262'"
using FloatBuffer = java.nio.FloatBuffer;
//UPGRADE_TODO: The type 'java.nio.IntBuffer' could not be found. If it was not included in the conversion, there may be compiler issues. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1262'"
using IntBuffer = java.nio.IntBuffer;
using BufferUtils = org.lwjgl.BufferUtils;
using ARBMultitexture = org.lwjgl.opengl.ARBMultitexture;
using GL11 = org.lwjgl.opengl.GL11;
using GL13 = org.lwjgl.opengl.GL13;
namespace Suake2.UI.render.lwjgl
{
	
	/// <summary> Main
	/// 
	/// </summary>
	/// <author>  cwei
	/// </author>
	public abstract class Main:Base
	{
		public Main()
		{
			InitBlock();
		}
		//UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'AnonymousClassxcommand_t' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'"
		private class AnonymousClassxcommand_t:xcommand_t
		{
			public AnonymousClassxcommand_t(Main enclosingInstance)
			{
				InitBlock(enclosingInstance);
			}
			private void  InitBlock(Main enclosingInstance)
			{
				this.enclosingInstance = enclosingInstance;
			}
			private Main enclosingInstance;
			public Main Enclosing_Instance
			{
				get
				{
					return enclosingInstance;
				}
				
			}
			public override void  execute()
			{
				Enclosing_Instance.GL_ImageList_f();
			}
		}
		//UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'AnonymousClassxcommand_t1' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'"
		private class AnonymousClassxcommand_t1:xcommand_t
		{
			public AnonymousClassxcommand_t1(Main enclosingInstance)
			{
				InitBlock(enclosingInstance);
			}
			private void  InitBlock(Main enclosingInstance)
			{
				this.enclosingInstance = enclosingInstance;
			}
			private Main enclosingInstance;
			public Main Enclosing_Instance
			{
				get
				{
					return enclosingInstance;
				}
				
			}
			public override void  execute()
			{
				Enclosing_Instance.GL_ScreenShot_f();
			}
		}
		//UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'AnonymousClassxcommand_t2' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'"
		private class AnonymousClassxcommand_t2:xcommand_t
		{
			public AnonymousClassxcommand_t2(Main enclosingInstance)
			{
				InitBlock(enclosingInstance);
			}
			private void  InitBlock(Main enclosingInstance)
			{
				this.enclosingInstance = enclosingInstance;
			}
			private Main enclosingInstance;
			public Main Enclosing_Instance
			{
				get
				{
					return enclosingInstance;
				}
				
			}
			public override void  execute()
			{
				Enclosing_Instance.Mod_Modellist_f();
			}
		}
		//UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'AnonymousClassxcommand_t3' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'"
		private class AnonymousClassxcommand_t3:xcommand_t
		{
			public AnonymousClassxcommand_t3(Main enclosingInstance)
			{
				InitBlock(enclosingInstance);
			}
			private void  InitBlock(Main enclosingInstance)
			{
				this.enclosingInstance = enclosingInstance;
			}
			private Main enclosingInstance;
			public Main Enclosing_Instance
			{
				get
				{
					return enclosingInstance;
				}
				
			}
			public override void  execute()
			{
				Enclosing_Instance.GL_Strings_f();
			}
		}
		private void  InitBlock()
		{
			GL_TEXTURE0 = GL13.GL_TEXTURE0;
			GL_TEXTURE1 = GL13.GL_TEXTURE1;
			r_world_matrix = BufferUtils.createFloatBuffer(16);
			for (int i = 0; i < NUM_BEAM_SEGS; i++)
			{
				start_points[i] = new float[3];
			}
			for (int i2 = 0; i2 < NUM_BEAM_SEGS; i2++)
			{
				end_points[i2] = new float[3];
			}
		}
		
		public static int[] d_8to24table = new int[256];
		
		internal int c_visible_lightmaps;
		internal int c_visible_textures;
		
		internal int registration_sequence;
		
		// this a hack for function pointer test
		// default disabled
		internal bool qglColorTableEXT = false;
		internal bool qglActiveTextureARB = false;
		internal bool qglPointParameterfEXT = false;
		internal bool qglLockArraysEXT = false;
		internal bool qwglSwapIntervalEXT = false;
		
		//	=================
		//  abstract methods
		//	=================
		protected internal abstract void  Draw_GetPalette();
		
		internal abstract void  GL_ImageList_f();
		internal abstract void  GL_ScreenShot_f();
		internal abstract void  GL_SetTexturePalette(int[] palette);
		internal abstract void  GL_Strings_f();
		
		internal abstract void  Mod_Modellist_f();
		internal abstract mleaf_t Mod_PointInLeaf(float[] point, model_t model);
		
		internal abstract void  GL_SetDefaultState();
		
		internal abstract void  GL_InitImages();
		internal abstract void  Mod_Init(); // Model.java
		internal abstract void  R_InitParticleTexture(); // MIsc.java
		internal abstract void  R_DrawAliasModel(entity_t e); // Mesh.java
		internal abstract void  R_DrawBrushModel(entity_t e); // Surf.java
		internal abstract void  Draw_InitLocal();
		internal abstract void  R_LightPoint(float[] p, float[] color);
		internal abstract void  R_PushDlights();
		internal abstract void  R_MarkLeaves();
		internal abstract void  R_DrawWorld();
		internal abstract void  R_RenderDlights();
		internal abstract void  R_DrawAlphaSurfaces();
		
		internal abstract void  Mod_FreeAll();
		
		internal abstract void  GL_ShutdownImages();
		internal abstract void  GL_Bind(int texnum);
		internal abstract void  GL_TexEnv(int mode);
		internal abstract void  GL_TextureMode(System.String string_Renamed);
		internal abstract void  GL_TextureAlphaMode(System.String string_Renamed);
		internal abstract void  GL_TextureSolidMode(System.String string_Renamed);
		internal abstract void  GL_UpdateSwapInterval();
		
		/*
		====================================================================
		
		from gl_rmain.c
		
		====================================================================
		*/
		
		//UPGRADE_NOTE: The initialization of  'GL_TEXTURE0' was moved to method 'InitBlock'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal int GL_TEXTURE0;
		//UPGRADE_NOTE: The initialization of  'GL_TEXTURE1' was moved to method 'InitBlock'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal int GL_TEXTURE1;
		
		internal model_t r_worldmodel;
		
		internal float gldepthmin, gldepthmax;
		
		internal glconfig_t gl_config = new glconfig_t();
		internal glstate_t gl_state = new glstate_t();
		
		internal image_t r_notexture; // use for bad textures
		internal image_t r_particletexture; // little dot for particles
		
		internal entity_t currententity;
		internal model_t currentmodel;
		
		internal cplane_t[] frustum = new cplane_t[]{new cplane_t(), new cplane_t(), new cplane_t(), new cplane_t()};
		
		internal int r_visframecount; // bumped when going to a new PVS
		internal int r_framecount; // used for dlight push checking
		
		internal int c_brush_polys, c_alias_polys;
		
		internal float[] v_blend = new float[]{0, 0, 0, 0}; // final blending color
		
		//
		//	   view origin
		//
		internal float[] vup = new float[]{0, 0, 0};
		internal float[] vpn = new float[]{0, 0, 0};
		internal float[] vright = new float[]{0, 0, 0};
		internal float[] r_origin = new float[]{0, 0, 0};
		
		//float r_world_matrix[] = new float[16];
		//UPGRADE_NOTE: The initialization of  'r_world_matrix' was moved to method 'InitBlock'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal FloatBuffer r_world_matrix;
		
		internal float[] r_base_world_matrix = new float[16];
		
		//
		//	   screen size info
		//
		internal refdef_t r_newrefdef = new refdef_t();
		
		internal int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2;
		
		internal cvar_t r_norefresh;
		internal cvar_t r_drawentities;
		internal cvar_t r_drawworld;
		internal cvar_t r_speeds;
		internal cvar_t r_fullbright;
		internal cvar_t r_novis;
		internal cvar_t r_nocull;
		internal cvar_t r_lerpmodels;
		internal cvar_t r_lefthand;
		
		internal cvar_t r_lightlevel;
		// FIXME: This is a HACK to get the client's light level
		
		internal cvar_t gl_nosubimage;
		internal cvar_t gl_allow_software;
		
		internal cvar_t gl_vertex_arrays;
		
		internal cvar_t gl_particle_min_size;
		internal cvar_t gl_particle_max_size;
		internal cvar_t gl_particle_size;
		internal cvar_t gl_particle_att_a;
		internal cvar_t gl_particle_att_b;
		internal cvar_t gl_particle_att_c;
		
		internal cvar_t gl_ext_swapinterval;
		internal cvar_t gl_ext_palettedtexture;
		internal cvar_t gl_ext_multitexture;
		internal cvar_t gl_ext_pointparameters;
		internal cvar_t gl_ext_compiled_vertex_array;
		
		internal cvar_t gl_log;
		internal cvar_t gl_bitdepth;
		internal cvar_t gl_drawbuffer;
		internal cvar_t gl_driver;
		internal cvar_t gl_lightmap;
		internal cvar_t gl_shadows;
		internal cvar_t gl_mode;
		internal cvar_t gl_dynamic;
		internal cvar_t gl_monolightmap;
		internal cvar_t gl_modulate;
		internal cvar_t gl_nobind;
		internal cvar_t gl_round_down;
		internal cvar_t gl_picmip;
		internal cvar_t gl_skymip;
		internal cvar_t gl_showtris;
		internal cvar_t gl_ztrick;
		internal cvar_t gl_finish;
		internal cvar_t gl_clear;
		internal cvar_t gl_cull;
		internal cvar_t gl_polyblend;
		internal cvar_t gl_flashblend;
		internal cvar_t gl_playermip;
		internal cvar_t gl_saturatelighting;
		internal cvar_t gl_swapinterval;
		internal cvar_t gl_texturemode;
		internal cvar_t gl_texturealphamode;
		internal cvar_t gl_texturesolidmode;
		internal cvar_t gl_lockpvs;
		
		internal cvar_t gl_3dlabs_broken;
		
		internal cvar_t vid_gamma;
		internal cvar_t vid_ref;
		
		// ============================================================================
		// to port from gl_rmain.c, ...
		// ============================================================================
		
		/// <summary> R_CullBox
		/// Returns true if the box is completely outside the frustum
		/// </summary>
		internal bool R_CullBox(float[] mins, float[] maxs)
		{
			//UPGRADE_ISSUE: The following fragment of code could not be parsed and was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1156'"
			assert(mins.length == 3 && maxs.length == 3): vec3_t bug;
			
			if (r_nocull.value_Renamed != 0)
				return false;
			
			for (int i = 0; i < 4; i++)
			{
				if (Math3D.BoxOnPlaneSide(mins, maxs, frustum[i]) == 2)
					return true;
			}
			return false;
		}
		
		/// <summary> R_RotateForEntity</summary>
		internal void  R_RotateForEntity(entity_t e)
		{
			gl.glTranslatef(e.origin[0], e.origin[1], e.origin[2]);
			
			gl.glRotatef(e.angles[1], 0, 0, 1);
			gl.glRotatef(- e.angles[0], 0, 1, 0);
			gl.glRotatef(- e.angles[2], 1, 0, 0);
		}
		
		/*
		=============================================================
		
		SPRITE MODELS
		
		=============================================================
		*/
		
		// stack variable
		//UPGRADE_NOTE: Final was removed from the declaration of 'point '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
		private float[] point = new float[]{0, 0, 0};
		/// <summary> R_DrawSpriteModel</summary>
		internal virtual void  R_DrawSpriteModel(entity_t e)
		{
			float alpha = 1.0F;
			
			qfiles.dsprframe_t frame;
			qfiles.dsprite_t psprite;
			
			// don't even bother culling, because it's just a single
			// polygon without a surface cache
			
			psprite = (qfiles.dsprite_t) currentmodel.extradata;
			
			e.frame %= psprite.numframes;
			
			frame = psprite.frames[e.frame];
			
			if ((e.flags & Defines.RF_TRANSLUCENT) != 0)
				alpha = e.alpha;
			
			if (alpha != 1.0F)
				gl.glEnable(GL11.GL_BLEND);
			
			gl.glColor4f(1, 1, 1, alpha);
			
			GL_Bind(currentmodel.skins[e.frame].texnum);
			
			GL_TexEnv(GL11.GL_MODULATE);
			
			if (alpha == 1.0)
				gl.glEnable(GL11.GL_ALPHA_TEST);
			else
				gl.glDisable(GL11.GL_ALPHA_TEST);
			
			gl.glBegin(GL11.GL_QUADS);
			
			gl.glTexCoord2f(0, 1);
			Math3D.VectorMA(e.origin, - frame.origin_y, vup, point);
			Math3D.VectorMA(point, - frame.origin_x, vright, point);
			gl.glVertex3f(point[0], point[1], point[2]);
			
			gl.glTexCoord2f(0, 0);
			Math3D.VectorMA(e.origin, frame.height - frame.origin_y, vup, point);
			Math3D.VectorMA(point, - frame.origin_x, vright, point);
			gl.glVertex3f(point[0], point[1], point[2]);
			
			gl.glTexCoord2f(1, 0);
			Math3D.VectorMA(e.origin, frame.height - frame.origin_y, vup, point);
			Math3D.VectorMA(point, frame.width - frame.origin_x, vright, point);
			gl.glVertex3f(point[0], point[1], point[2]);
			
			gl.glTexCoord2f(1, 1);
			Math3D.VectorMA(e.origin, - frame.origin_y, vup, point);
			Math3D.VectorMA(point, frame.width - frame.origin_x, vright, point);
			gl.glVertex3f(point[0], point[1], point[2]);
			
			gl.glEnd();
			
			gl.glDisable(GL11.GL_ALPHA_TEST);
			GL_TexEnv(GL11.GL_REPLACE);
			
			if (alpha != 1.0F)
				gl.glDisable(GL11.GL_BLEND);
			
			gl.glColor4f(1, 1, 1, 1);
		}
		
		// ==================================================================================
		
		// stack variable
		//UPGRADE_NOTE: Final was removed from the declaration of 'shadelight '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
		private float[] shadelight = new float[]{0, 0, 0};
		/// <summary> R_DrawNullModel</summary>
		internal virtual void  R_DrawNullModel()
		{
			if ((currententity.flags & Defines.RF_FULLBRIGHT) != 0)
			{
				// cwei wollte blau: shadelight[0] = shadelight[1] = shadelight[2] = 1.0F;
				shadelight[0] = shadelight[1] = shadelight[2] = 0.0F;
				shadelight[2] = 0.8F;
			}
			else
			{
				R_LightPoint(currententity.origin, shadelight);
			}
			
			gl.glPushMatrix();
			R_RotateForEntity(currententity);
			
			gl.glDisable(GL11.GL_TEXTURE_2D);
			gl.glColor3f(shadelight[0], shadelight[1], shadelight[2]);
			
			// this replaces the TRIANGLE_FAN
			//glut.glutWireCube(gl, 20);
			
			gl.glBegin(GL11.GL_TRIANGLE_FAN);
			gl.glVertex3f(0, 0, - 16);
			int i;
			for (i = 0; i <= 4; i++)
			{
				//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
				gl.glVertex3f((float) (16.0f * System.Math.Cos(i * System.Math.PI / 2)), (float) (16.0f * System.Math.Sin(i * System.Math.PI / 2)), 0.0f);
			}
			gl.glEnd();
			
			gl.glBegin(GL11.GL_TRIANGLE_FAN);
			gl.glVertex3f(0, 0, 16);
			for (i = 4; i >= 0; i--)
			{
				//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
				gl.glVertex3f((float) (16.0f * System.Math.Cos(i * System.Math.PI / 2)), (float) (16.0f * System.Math.Sin(i * System.Math.PI / 2)), 0.0f);
			}
			gl.glEnd();
			
			
			gl.glColor3f(1, 1, 1);
			gl.glPopMatrix();
			gl.glEnable(GL11.GL_TEXTURE_2D);
		}
		
		/// <summary> R_DrawEntitiesOnList</summary>
		internal virtual void  R_DrawEntitiesOnList()
		{
			if (r_drawentities.value_Renamed == 0.0f)
				return ;
			
			// draw non-transparent first
			int i;
			for (i = 0; i < r_newrefdef.num_entities; i++)
			{
				currententity = r_newrefdef.entities[i];
				if ((currententity.flags & Defines.RF_TRANSLUCENT) != 0)
					continue; // solid
				
				if ((currententity.flags & Defines.RF_BEAM) != 0)
				{
					R_DrawBeam(currententity);
				}
				else
				{
					currentmodel = currententity.model;
					if (currentmodel == null)
					{
						R_DrawNullModel();
						continue;
					}
					switch (currentmodel.type)
					{
						
						case mod_alias: 
							R_DrawAliasModel(currententity);
							break;
						
						case mod_brush: 
							R_DrawBrushModel(currententity);
							break;
						
						case mod_sprite: 
							R_DrawSpriteModel(currententity);
							break;
						
						default: 
							Com.Error(Defines.ERR_DROP, "Bad modeltype");
							break;
						
					}
				}
			}
			// draw transparent entities
			// we could sort these if it ever becomes a problem...
			gl.glDepthMask(false); // no z writes
			for (i = 0; i < r_newrefdef.num_entities; i++)
			{
				currententity = r_newrefdef.entities[i];
				if ((currententity.flags & Defines.RF_TRANSLUCENT) == 0)
					continue; // solid
				
				if ((currententity.flags & Defines.RF_BEAM) != 0)
				{
					R_DrawBeam(currententity);
				}
				else
				{
					currentmodel = currententity.model;
					
					if (currentmodel == null)
					{
						R_DrawNullModel();
						continue;
					}
					switch (currentmodel.type)
					{
						
						case mod_alias: 
							R_DrawAliasModel(currententity);
							break;
						
						case mod_brush: 
							R_DrawBrushModel(currententity);
							break;
						
						case mod_sprite: 
							R_DrawSpriteModel(currententity);
							break;
						
						default: 
							Com.Error(Defines.ERR_DROP, "Bad modeltype");
							break;
						
					}
				}
			}
			gl.glDepthMask(true); // back to writing
		}
		
		// stack variable 
		//UPGRADE_NOTE: Final was removed from the declaration of 'up '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
		private float[] up = new float[]{0, 0, 0};
		//UPGRADE_NOTE: Final was removed from the declaration of 'right '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
		private float[] right = new float[]{0, 0, 0};
		/// <summary> GL_DrawParticles</summary>
		internal virtual void  GL_DrawParticles(int num_particles)
		{
			float origin_x, origin_y, origin_z;
			
			Math3D.VectorScale(vup, 1.5f, up);
			Math3D.VectorScale(vright, 1.5f, right);
			
			GL_Bind(r_particletexture.texnum);
			gl.glDepthMask(false); // no z buffering
			gl.glEnable(GL11.GL_BLEND);
			GL_TexEnv(GL11.GL_MODULATE);
			
			gl.glBegin(GL11.GL_TRIANGLES);
			
			FloatBuffer sourceVertices = particle_t.vertexArray;
			IntBuffer sourceColors = particle_t.colorArray;
			float scale;
			int color;
			for (int j = 0, i = 0; i < num_particles; i++)
			{
				origin_x = sourceVertices.get_Renamed(j++);
				origin_y = sourceVertices.get_Renamed(j++);
				origin_z = sourceVertices.get_Renamed(j++);
				
				// hack a scale up to keep particles from disapearing
				scale = (origin_x - r_origin[0]) * vpn[0] + (origin_y - r_origin[1]) * vpn[1] + (origin_z - r_origin[2]) * vpn[2];
				
				scale = (scale < 20)?1:1 + scale * 0.004f;
				
				color = sourceColors.get_Renamed(i);
				
				gl.glColor4ub((sbyte) ((color) & 0xFF), (sbyte) ((color >> 8) & 0xFF), (sbyte) ((color >> 16) & 0xFF), (sbyte) ((SupportClass.URShift(color, 24))));
				// first vertex
				gl.glTexCoord2f(0.0625f, 0.0625f);
				gl.glVertex3f(origin_x, origin_y, origin_z);
				// second vertex
				gl.glTexCoord2f(1.0625f, 0.0625f);
				gl.glVertex3f(origin_x + up[0] * scale, origin_y + up[1] * scale, origin_z + up[2] * scale);
				// third vertex
				gl.glTexCoord2f(0.0625f, 1.0625f);
				gl.glVertex3f(origin_x + right[0] * scale, origin_y + right[1] * scale, origin_z + right[2] * scale);
			}
			gl.glEnd();
			
			gl.glDisable(GL11.GL_BLEND);
			gl.glColor4f(1, 1, 1, 1);
			gl.glDepthMask(true); // back to normal Z buffering
			GL_TexEnv(GL11.GL_REPLACE);
		}
		
		/// <summary> R_DrawParticles</summary>
		internal virtual void  R_DrawParticles()
		{
			
			if (gl_ext_pointparameters.value_Renamed != 0.0f && qglPointParameterfEXT)
			{
				
				//gl.glEnableClientState(GL11.GL_VERTEX_ARRAY);
				gl.glVertexPointer(3, 0, particle_t.vertexArray);
				gl.glEnableClientState(GL11.GL_COLOR_ARRAY);
				gl.glColorPointer(4, true, 0, particle_t.ColorAsByteBuffer);
				
				gl.glDepthMask(false);
				gl.glEnable(GL11.GL_BLEND);
				gl.glDisable(GL11.GL_TEXTURE_2D);
				gl.glPointSize(gl_particle_size.value_Renamed);
				
				gl.glDrawArrays(GL11.GL_POINTS, 0, r_newrefdef.num_particles);
				
				gl.glDisableClientState(GL11.GL_COLOR_ARRAY);
				//gl.glDisableClientState(GL11.GL_VERTEX_ARRAY);
				
				gl.glDisable(GL11.GL_BLEND);
				gl.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
				gl.glDepthMask(true);
				gl.glEnable(GL11.GL_TEXTURE_2D);
			}
			else
			{
				GL_DrawParticles(r_newrefdef.num_particles);
			}
		}
		
		/// <summary> R_PolyBlend</summary>
		internal virtual void  R_PolyBlend()
		{
			if (gl_polyblend.value_Renamed == 0.0f)
				return ;
			
			if (v_blend[3] == 0.0f)
				return ;
			
			gl.glDisable(GL11.GL_ALPHA_TEST);
			gl.glEnable(GL11.GL_BLEND);
			gl.glDisable(GL11.GL_DEPTH_TEST);
			gl.glDisable(GL11.GL_TEXTURE_2D);
			
			gl.glLoadIdentity();
			
			// FIXME: get rid of these
			gl.glRotatef(- 90, 1, 0, 0); // put Z going up
			gl.glRotatef(90, 0, 0, 1); // put Z going up
			
			gl.glColor4f(v_blend[0], v_blend[1], v_blend[2], v_blend[3]);
			
			gl.glBegin(GL11.GL_QUADS);
			
			gl.glVertex3f(10, 100, 100);
			gl.glVertex3f(10, - 100, 100);
			gl.glVertex3f(10, - 100, - 100);
			gl.glVertex3f(10, 100, - 100);
			gl.glEnd();
			
			gl.glDisable(GL11.GL_BLEND);
			gl.glEnable(GL11.GL_TEXTURE_2D);
			gl.glEnable(GL11.GL_ALPHA_TEST);
			
			gl.glColor4f(1, 1, 1, 1);
		}
		
		// =======================================================================
		
		/// <summary> SignbitsForPlane</summary>
		internal virtual int SignbitsForPlane(cplane_t out_Renamed)
		{
			// for fast box on planeside test
			int bits = 0;
			for (int j = 0; j < 3; j++)
			{
				if (out_Renamed.normal[j] < 0)
					bits |= (1 << j);
			}
			return bits;
		}
		
		/// <summary> R_SetFrustum</summary>
		internal virtual void  R_SetFrustum()
		{
			// rotate VPN right by FOV_X/2 degrees
			Math3D.RotatePointAroundVector(frustum[0].normal, vup, vpn, - (90f - r_newrefdef.fov_x / 2f));
			// rotate VPN left by FOV_X/2 degrees
			Math3D.RotatePointAroundVector(frustum[1].normal, vup, vpn, 90f - r_newrefdef.fov_x / 2f);
			// rotate VPN up by FOV_X/2 degrees
			Math3D.RotatePointAroundVector(frustum[2].normal, vright, vpn, 90f - r_newrefdef.fov_y / 2f);
			// rotate VPN down by FOV_X/2 degrees
			Math3D.RotatePointAroundVector(frustum[3].normal, vright, vpn, - (90f - r_newrefdef.fov_y / 2f));
			
			for (int i = 0; i < 4; i++)
			{
				frustum[i].type = (sbyte) (Defines.PLANE_ANYZ);
				frustum[i].dist = Math3D.DotProduct(r_origin, frustum[i].normal);
				frustum[i].signbits = (sbyte) SignbitsForPlane(frustum[i]);
			}
		}
		
		// =======================================================================
		
		// stack variable
		//UPGRADE_NOTE: Final was removed from the declaration of 'temp '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
		private float[] temp = new float[]{0, 0, 0};
		/// <summary> R_SetupFrame</summary>
		internal virtual void  R_SetupFrame()
		{
			r_framecount++;
			
			//	build the transformation matrix for the given view angles
			Math3D.VectorCopy(r_newrefdef.vieworg, r_origin);
			
			Math3D.AngleVectors(r_newrefdef.viewangles, vpn, vright, vup);
			
			//	current viewcluster
			mleaf_t leaf;
			if ((r_newrefdef.rdflags & Defines.RDF_NOWORLDMODEL) == 0)
			{
				r_oldviewcluster = r_viewcluster;
				r_oldviewcluster2 = r_viewcluster2;
				leaf = Mod_PointInLeaf(r_origin, r_worldmodel);
				r_viewcluster = r_viewcluster2 = leaf.cluster;
				
				// check above and below so crossing solid water doesn't draw wrong
				if (leaf.contents == 0)
				{
					// look down a bit
					Math3D.VectorCopy(r_origin, temp);
					temp[2] -= 16;
					leaf = Mod_PointInLeaf(temp, r_worldmodel);
					if ((leaf.contents & Defines.CONTENTS_SOLID) == 0 && (leaf.cluster != r_viewcluster2))
						r_viewcluster2 = leaf.cluster;
				}
				else
				{
					// look up a bit
					Math3D.VectorCopy(r_origin, temp);
					temp[2] += 16;
					leaf = Mod_PointInLeaf(temp, r_worldmodel);
					if ((leaf.contents & Defines.CONTENTS_SOLID) == 0 && (leaf.cluster != r_viewcluster2))
						r_viewcluster2 = leaf.cluster;
				}
			}
			
			for (int i = 0; i < 4; i++)
				v_blend[i] = r_newrefdef.blend[i];
			
			c_brush_polys = 0;
			c_alias_polys = 0;
			
			// clear out the portion of the screen that the NOWORLDMODEL defines
			if ((r_newrefdef.rdflags & Defines.RDF_NOWORLDMODEL) != 0)
			{
				gl.glEnable(GL11.GL_SCISSOR_TEST);
				gl.glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
				gl.glScissor(r_newrefdef.x, vid.height - r_newrefdef.height - r_newrefdef.y, r_newrefdef.width, r_newrefdef.height);
				gl.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
				gl.glClearColor(1.0f, 0.0f, 0.5f, 0.5f);
				gl.glDisable(GL11.GL_SCISSOR_TEST);
			}
		}
		
		/// <summary> MYgluPerspective
		/// 
		/// </summary>
		/// <param name="fovy">
		/// </param>
		/// <param name="aspect">
		/// </param>
		/// <param name="zNear">
		/// </param>
		/// <param name="zFar">
		/// </param>
		internal virtual void  MYgluPerspective(double fovy, double aspect, double zNear, double zFar)
		{
			double ymax = zNear * System.Math.Tan(fovy * System.Math.PI / 360.0);
			double ymin = - ymax;
			
			double xmin = ymin * aspect;
			double xmax = ymax * aspect;
			
			xmin += (- (2 * gl_state.camera_separation)) / zNear;
			xmax += (- (2 * gl_state.camera_separation)) / zNear;
			
			gl.glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
		}
		
		/// <summary> R_SetupGL</summary>
		internal virtual void  R_SetupGL()
		{
			
			//
			// set up viewport
			//
			//int x = (int) Math.floor(r_newrefdef.x * vid.width / vid.width);
			int x = r_newrefdef.x;
			//int x2 = (int) Math.ceil((r_newrefdef.x + r_newrefdef.width) * vid.width / vid.width);
			int x2 = r_newrefdef.x + r_newrefdef.width;
			//int y = (int) Math.floor(vid.height - r_newrefdef.y * vid.height / vid.height);
			int y = vid.height - r_newrefdef.y;
			//int y2 = (int) Math.ceil(vid.height - (r_newrefdef.y + r_newrefdef.height) * vid.height / vid.height);
			int y2 = vid.height - (r_newrefdef.y + r_newrefdef.height);
			
			int w = x2 - x;
			int h = y - y2;
			
			gl.glViewport(x, y2, w, h);
			
			//
			// set up projection matrix
			//
			//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
			float screenaspect = (float) r_newrefdef.width / r_newrefdef.height;
			gl.glMatrixMode(GL11.GL_PROJECTION);
			gl.glLoadIdentity();
			MYgluPerspective(r_newrefdef.fov_y, screenaspect, 4, 4096);
			
			gl.glCullFace(GL11.GL_FRONT);
			
			gl.glMatrixMode(GL11.GL_MODELVIEW);
			gl.glLoadIdentity();
			
			gl.glRotatef(- 90, 1, 0, 0); // put Z going up
			gl.glRotatef(90, 0, 0, 1); // put Z going up
			gl.glRotatef(- r_newrefdef.viewangles[2], 1, 0, 0);
			gl.glRotatef(- r_newrefdef.viewangles[0], 0, 1, 0);
			gl.glRotatef(- r_newrefdef.viewangles[1], 0, 0, 1);
			gl.glTranslatef(- r_newrefdef.vieworg[0], - r_newrefdef.vieworg[1], - r_newrefdef.vieworg[2]);
			
			gl.glGetFloat(GL11.GL_MODELVIEW_MATRIX, r_world_matrix);
			r_world_matrix.clear();
			
			//
			// set drawing parms
			//
			if (gl_cull.value_Renamed != 0.0f)
				gl.glEnable(GL11.GL_CULL_FACE);
			else
				gl.glDisable(GL11.GL_CULL_FACE);
			
			gl.glDisable(GL11.GL_BLEND);
			gl.glDisable(GL11.GL_ALPHA_TEST);
			gl.glEnable(GL11.GL_DEPTH_TEST);
		}
		
		internal int trickframe = 0;
		
		/// <summary> R_Clear</summary>
		internal virtual void  R_Clear()
		{
			if (gl_ztrick.value_Renamed != 0.0f)
			{
				
				if (gl_clear.value_Renamed != 0.0f)
				{
					gl.glClear(GL11.GL_COLOR_BUFFER_BIT);
				}
				
				trickframe++;
				if ((trickframe & 1) != 0)
				{
					gldepthmin = 0;
					gldepthmax = 0.49999f;
					gl.glDepthFunc(GL11.GL_LEQUAL);
				}
				else
				{
					gldepthmin = 1;
					gldepthmax = 0.5f;
					gl.glDepthFunc(GL11.GL_GEQUAL);
				}
			}
			else
			{
				if (gl_clear.value_Renamed != 0.0f)
					gl.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
				else
					gl.glClear(GL11.GL_DEPTH_BUFFER_BIT);
				
				gldepthmin = 0;
				gldepthmax = 1;
				gl.glDepthFunc(GL11.GL_LEQUAL);
			}
			gl.glDepthRange(gldepthmin, gldepthmax);
		}
		
		/// <summary> R_Flash</summary>
		internal virtual void  R_Flash()
		{
			R_PolyBlend();
		}
		
		/// <summary> R_RenderView
		/// r_newrefdef must be set before the first call
		/// </summary>
		internal virtual void  R_RenderView(refdef_t fd)
		{
			
			if (r_norefresh.value_Renamed != 0.0f)
				return ;
			
			r_newrefdef = fd;
			
			// included by cwei
			if (r_newrefdef == null)
			{
				Com.Error(Defines.ERR_DROP, "R_RenderView: refdef_t fd is null");
			}
			
			if (r_worldmodel == null && (r_newrefdef.rdflags & Defines.RDF_NOWORLDMODEL) == 0)
				Com.Error(Defines.ERR_DROP, "R_RenderView: NULL worldmodel");
			
			if (r_speeds.value_Renamed != 0.0f)
			{
				c_brush_polys = 0;
				c_alias_polys = 0;
			}
			
			R_PushDlights();
			
			if (gl_finish.value_Renamed != 0.0f)
				gl.glFinish();
			
			R_SetupFrame();
			
			R_SetFrustum();
			
			R_SetupGL();
			
			R_MarkLeaves(); // done here so we know if we're in water
			
			R_DrawWorld();
			
			R_DrawEntitiesOnList();
			
			R_RenderDlights();
			
			R_DrawParticles();
			
			R_DrawAlphaSurfaces();
			
			R_Flash();
			
			if (r_speeds.value_Renamed != 0.0f)
			{
				VID.Printf(Defines.PRINT_ALL, "%4i wpoly %4i epoly %i tex %i lmaps\n", new Vargs(4).add(c_brush_polys).add(c_alias_polys).add(c_visible_textures).add(c_visible_lightmaps));
			}
		}
		
		/// <summary> R_SetGL2D</summary>
		internal virtual void  R_SetGL2D()
		{
			// set 2D virtual screen size
			gl.glViewport(0, 0, vid.width, vid.height);
			gl.glMatrixMode(GL11.GL_PROJECTION);
			gl.glLoadIdentity();
			gl.glOrtho(0, vid.width, vid.height, 0, - 99999, 99999);
			gl.glMatrixMode(GL11.GL_MODELVIEW);
			gl.glLoadIdentity();
			gl.glDisable(GL11.GL_DEPTH_TEST);
			gl.glDisable(GL11.GL_CULL_FACE);
			gl.glDisable(GL11.GL_BLEND);
			gl.glEnable(GL11.GL_ALPHA_TEST);
			gl.glColor4f(1, 1, 1, 1);
		}
		
		// stack variable
		//UPGRADE_NOTE: Final was removed from the declaration of 'light '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
		private float[] light = new float[]{0, 0, 0};
		/// <summary>	R_SetLightLevel</summary>
		internal virtual void  R_SetLightLevel()
		{
			if ((r_newrefdef.rdflags & Defines.RDF_NOWORLDMODEL) != 0)
				return ;
			
			// save off light value for server to look at (BIG HACK!)
			
			R_LightPoint(r_newrefdef.vieworg, light);
			
			// pick the greatest component, which should be the same
			// as the mono value returned by software
			if (light[0] > light[1])
			{
				if (light[0] > light[2])
					r_lightlevel.value_Renamed = 150 * light[0];
				else
					r_lightlevel.value_Renamed = 150 * light[2];
			}
			else
			{
				if (light[1] > light[2])
					r_lightlevel.value_Renamed = 150 * light[1];
				else
					r_lightlevel.value_Renamed = 150 * light[2];
			}
		}
		
		/// <summary> R_RenderFrame</summary>
		protected internal virtual void  R_RenderFrame(refdef_t fd)
		{
			R_RenderView(fd);
			R_SetLightLevel();
			R_SetGL2D();
		}
		
		/// <summary> R_Register</summary>
		protected internal virtual void  R_Register()
		{
			r_lefthand = Cvar.Get("hand", "0", Globals.CVAR_USERINFO | Globals.CVAR_ARCHIVE);
			r_norefresh = Cvar.Get("r_norefresh", "0", 0);
			r_fullbright = Cvar.Get("r_fullbright", "0", 0);
			r_drawentities = Cvar.Get("r_drawentities", "1", 0);
			r_drawworld = Cvar.Get("r_drawworld", "1", 0);
			r_novis = Cvar.Get("r_novis", "0", 0);
			r_nocull = Cvar.Get("r_nocull", "0", 0);
			r_lerpmodels = Cvar.Get("r_lerpmodels", "1", 0);
			r_speeds = Cvar.Get("r_speeds", "0", 0);
			
			r_lightlevel = Cvar.Get("r_lightlevel", "1", 0);
			
			gl_nosubimage = Cvar.Get("gl_nosubimage", "0", 0);
			gl_allow_software = Cvar.Get("gl_allow_software", "0", 0);
			
			gl_particle_min_size = Cvar.Get("gl_particle_min_size", "2", Globals.CVAR_ARCHIVE);
			gl_particle_max_size = Cvar.Get("gl_particle_max_size", "40", Globals.CVAR_ARCHIVE);
			gl_particle_size = Cvar.Get("gl_particle_size", "40", Globals.CVAR_ARCHIVE);
			gl_particle_att_a = Cvar.Get("gl_particle_att_a", "0.01", Globals.CVAR_ARCHIVE);
			gl_particle_att_b = Cvar.Get("gl_particle_att_b", "0.0", Globals.CVAR_ARCHIVE);
			gl_particle_att_c = Cvar.Get("gl_particle_att_c", "0.01", Globals.CVAR_ARCHIVE);
			
			gl_modulate = Cvar.Get("gl_modulate", "1.5", Globals.CVAR_ARCHIVE);
			gl_log = Cvar.Get("gl_log", "0", 0);
			gl_bitdepth = Cvar.Get("gl_bitdepth", "0", 0);
			gl_mode = Cvar.Get("gl_mode", "3", Globals.CVAR_ARCHIVE); // 640x480
			gl_lightmap = Cvar.Get("gl_lightmap", "0", 0);
			gl_shadows = Cvar.Get("gl_shadows", "0", Globals.CVAR_ARCHIVE);
			gl_dynamic = Cvar.Get("gl_dynamic", "1", 0);
			gl_nobind = Cvar.Get("gl_nobind", "0", 0);
			gl_round_down = Cvar.Get("gl_round_down", "1", 0);
			gl_picmip = Cvar.Get("gl_picmip", "0", 0);
			gl_skymip = Cvar.Get("gl_skymip", "0", 0);
			gl_showtris = Cvar.Get("gl_showtris", "0", 0);
			gl_ztrick = Cvar.Get("gl_ztrick", "0", 0);
			gl_finish = Cvar.Get("gl_finish", "0", Globals.CVAR_ARCHIVE);
			gl_clear = Cvar.Get("gl_clear", "0", 0);
			gl_cull = Cvar.Get("gl_cull", "1", 0);
			gl_polyblend = Cvar.Get("gl_polyblend", "1", 0);
			gl_flashblend = Cvar.Get("gl_flashblend", "0", 0);
			gl_playermip = Cvar.Get("gl_playermip", "0", 0);
			gl_monolightmap = Cvar.Get("gl_monolightmap", "0", 0);
			gl_driver = Cvar.Get("gl_driver", "opengl32", Globals.CVAR_ARCHIVE);
			gl_texturemode = Cvar.Get("gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", Globals.CVAR_ARCHIVE);
			gl_texturealphamode = Cvar.Get("gl_texturealphamode", "default", Globals.CVAR_ARCHIVE);
			gl_texturesolidmode = Cvar.Get("gl_texturesolidmode", "default", Globals.CVAR_ARCHIVE);
			gl_lockpvs = Cvar.Get("gl_lockpvs", "0", 0);
			
			gl_vertex_arrays = Cvar.Get("gl_vertex_arrays", "1", Globals.CVAR_ARCHIVE);
			
			gl_ext_swapinterval = Cvar.Get("gl_ext_swapinterval", "1", Globals.CVAR_ARCHIVE);
			gl_ext_palettedtexture = Cvar.Get("gl_ext_palettedtexture", "0", Globals.CVAR_ARCHIVE);
			gl_ext_multitexture = Cvar.Get("gl_ext_multitexture", "1", Globals.CVAR_ARCHIVE);
			gl_ext_pointparameters = Cvar.Get("gl_ext_pointparameters", "1", Globals.CVAR_ARCHIVE);
			gl_ext_compiled_vertex_array = Cvar.Get("gl_ext_compiled_vertex_array", "1", Globals.CVAR_ARCHIVE);
			
			gl_drawbuffer = Cvar.Get("gl_drawbuffer", "GL_BACK", 0);
			gl_swapinterval = Cvar.Get("gl_swapinterval", "0", Globals.CVAR_ARCHIVE);
			
			gl_saturatelighting = Cvar.Get("gl_saturatelighting", "0", 0);
			
			gl_3dlabs_broken = Cvar.Get("gl_3dlabs_broken", "1", Globals.CVAR_ARCHIVE);
			
			vid_fullscreen = Cvar.Get("vid_fullscreen", "0", Globals.CVAR_ARCHIVE);
			vid_gamma = Cvar.Get("vid_gamma", "1.0", Globals.CVAR_ARCHIVE);
			vid_ref = Cvar.Get("vid_ref", "lwjgl", Globals.CVAR_ARCHIVE);
			
			Cmd.AddCommand("imagelist", new AnonymousClassxcommand_t(this));
			
			Cmd.AddCommand("screenshot", new AnonymousClassxcommand_t1(this));
			Cmd.AddCommand("modellist", new AnonymousClassxcommand_t2(this));
			Cmd.AddCommand("gl_strings", new AnonymousClassxcommand_t3(this));
		}
		
		/// <summary> R_SetMode</summary>
		protected internal virtual bool R_SetMode()
		{
			bool fullscreen = (vid_fullscreen.value_Renamed > 0.0f);
			
			vid_fullscreen.modified = false;
			gl_mode.modified = false;
			
			System.Drawing.Size dim = new System.Drawing.Size(vid.width, vid.height);
			
			int err; //  enum rserr_t
			//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
			//UPGRADE_NOTE: ref keyword was added to struct-type parameters. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1303'"
			if ((err = GLimp_SetMode(ref dim, (int) gl_mode.value_Renamed, fullscreen)) == rserr_ok)
			{
				//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
				gl_state.prev_mode = (int) gl_mode.value_Renamed;
			}
			else
			{
				if (err == rserr_invalid_fullscreen)
				{
					Cvar.SetValue("vid_fullscreen", 0);
					vid_fullscreen.modified = false;
					VID.Printf(Defines.PRINT_ALL, "ref_gl::R_SetMode() - fullscreen unavailable in this mode\n");
					//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
					//UPGRADE_NOTE: ref keyword was added to struct-type parameters. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1303'"
					if ((err = GLimp_SetMode(ref dim, (int) gl_mode.value_Renamed, false)) == rserr_ok)
						return true;
				}
				else if (err == rserr_invalid_mode)
				{
					Cvar.SetValue("gl_mode", gl_state.prev_mode);
					gl_mode.modified = false;
					VID.Printf(Defines.PRINT_ALL, "ref_gl::R_SetMode() - invalid mode\n");
				}
				
				// try setting it back to something safe
				//UPGRADE_NOTE: ref keyword was added to struct-type parameters. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1303'"
				if ((err = GLimp_SetMode(ref dim, gl_state.prev_mode, false)) != rserr_ok)
				{
					VID.Printf(Defines.PRINT_ALL, "ref_gl::R_SetMode() - could not revert to safe mode\n");
					return false;
				}
			}
			return true;
		}
		
		internal float[] r_turbsin = new float[256];
		
		/// <summary> R_Init</summary>
		protected internal virtual bool R_Init(int vid_xpos, int vid_ypos)
		{
			
			//UPGRADE_ISSUE: The following fragment of code could not be parsed and was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1156'"
			assert(Warp.SIN.length == 256): warpsin table bug;
			
			// fill r_turbsin
			for (int j = 0; j < 256; j++)
			{
				r_turbsin[j] = Warp.SIN[j] * 0.5f;
			}
			
			VID.Printf(Defines.PRINT_ALL, "ref_gl version: " + REF_VERSION + '\n');
			
			Draw_GetPalette();
			
			R_Register();
			
			// set our "safe" modes
			gl_state.prev_mode = 3;
			
			// create the window and set up the context
			if (!R_SetMode())
			{
				VID.Printf(Defines.PRINT_ALL, "ref_gl::R_Init() - could not R_SetMode()\n");
				return false;
			}
			return true;
		}
		
		/// <summary> R_Init2</summary>
		protected internal override bool R_Init2()
		{
			VID.MenuInit();
			
			/*
			** get our various GL strings
			*/
			gl_config.vendor_string = gl.glGetString(GL11.GL_VENDOR);
			VID.Printf(Defines.PRINT_ALL, "GL_VENDOR: " + gl_config.vendor_string + '\n');
			gl_config.renderer_string = gl.glGetString(GL11.GL_RENDERER);
			VID.Printf(Defines.PRINT_ALL, "GL_RENDERER: " + gl_config.renderer_string + '\n');
			gl_config.version_string = gl.glGetString(GL11.GL_VERSION);
			VID.Printf(Defines.PRINT_ALL, "GL_VERSION: " + gl_config.version_string + '\n');
			gl_config.extensions_string = gl.glGetString(GL11.GL_EXTENSIONS);
			VID.Printf(Defines.PRINT_ALL, "GL_EXTENSIONS: " + gl_config.extensions_string + '\n');
			
			gl_config.parseOpenGLVersion();
			
			System.String renderer_buffer = gl_config.renderer_string.ToLower();
			System.String vendor_buffer = gl_config.vendor_string.ToLower();
			
			if (renderer_buffer.IndexOf("voodoo") >= 0)
			{
				if (renderer_buffer.IndexOf("rush") < 0)
					gl_config.renderer = GL_RENDERER_VOODOO;
				else
					gl_config.renderer = GL_RENDERER_VOODOO_RUSH;
			}
			else if (vendor_buffer.IndexOf("sgi") >= 0)
				gl_config.renderer = GL_RENDERER_SGI;
			else if (renderer_buffer.IndexOf("permedia") >= 0)
				gl_config.renderer = GL_RENDERER_PERMEDIA2;
			else if (renderer_buffer.IndexOf("glint") >= 0)
				gl_config.renderer = GL_RENDERER_GLINT_MX;
			else if (renderer_buffer.IndexOf("glzicd") >= 0)
				gl_config.renderer = GL_RENDERER_REALIZM;
			else if (renderer_buffer.IndexOf("gdi") >= 0)
				gl_config.renderer = GL_RENDERER_MCD;
			else if (renderer_buffer.IndexOf("pcx2") >= 0)
				gl_config.renderer = GL_RENDERER_PCX2;
			else if (renderer_buffer.IndexOf("verite") >= 0)
				gl_config.renderer = GL_RENDERER_RENDITION;
			else
				gl_config.renderer = GL_RENDERER_OTHER;
			
			System.String monolightmap = gl_monolightmap.string_Renamed.ToUpper();
			if (monolightmap.Length < 2 || monolightmap[1] != 'F')
			{
				if (gl_config.renderer == GL_RENDERER_PERMEDIA2)
				{
					Cvar.Set("gl_monolightmap", "A");
					VID.Printf(Defines.PRINT_ALL, "...using gl_monolightmap 'a'\n");
				}
				else if ((gl_config.renderer & GL_RENDERER_POWERVR) != 0)
				{
					Cvar.Set("gl_monolightmap", "0");
				}
				else
				{
					Cvar.Set("gl_monolightmap", "0");
				}
			}
			
			// power vr can't have anything stay in the framebuffer, so
			// the screen needs to redraw the tiled background every frame
			if ((gl_config.renderer & GL_RENDERER_POWERVR) != 0)
			{
				Cvar.Set("scr_drawall", "1");
			}
			else
			{
				Cvar.Set("scr_drawall", "0");
			}
			
			// MCD has buffering issues
			if (gl_config.renderer == GL_RENDERER_MCD)
			{
				Cvar.SetValue("gl_finish", 1);
			}
			
			if ((gl_config.renderer & GL_RENDERER_3DLABS) != 0)
			{
				if (gl_3dlabs_broken.value_Renamed != 0.0f)
					gl_config.allow_cds = false;
				else
					gl_config.allow_cds = true;
			}
			else
			{
				gl_config.allow_cds = true;
			}
			
			if (gl_config.allow_cds)
				VID.Printf(Defines.PRINT_ALL, "...allowing CDS\n");
			else
				VID.Printf(Defines.PRINT_ALL, "...disabling CDS\n");
			
			/*
			** grab extensions
			*/
			if (gl_config.extensions_string.IndexOf("GL_EXT_compiled_vertex_array") >= 0 || gl_config.extensions_string.IndexOf("GL_SGI_compiled_vertex_array") >= 0)
			{
				VID.Printf(Defines.PRINT_ALL, "...enabling GL_EXT_compiled_vertex_array\n");
				//		 qglLockArraysEXT = ( void * ) qwglGetProcAddress( "glLockArraysEXT" );
				if (gl_ext_compiled_vertex_array.value_Renamed != 0.0f)
					qglLockArraysEXT = true;
				else
					qglLockArraysEXT = false;
				//		 qglUnlockArraysEXT = ( void * ) qwglGetProcAddress( "glUnlockArraysEXT" );
				//qglUnlockArraysEXT = true;
			}
			else
			{
				VID.Printf(Defines.PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n");
				qglLockArraysEXT = false;
			}
			
			if (gl_config.extensions_string.IndexOf("WGL_EXT_swap_control") >= 0)
			{
				qwglSwapIntervalEXT = true;
				VID.Printf(Defines.PRINT_ALL, "...enabling WGL_EXT_swap_control\n");
			}
			else
			{
				qwglSwapIntervalEXT = false;
				VID.Printf(Defines.PRINT_ALL, "...WGL_EXT_swap_control not found\n");
			}
			
			if (gl_config.extensions_string.IndexOf("GL_EXT_point_parameters") >= 0)
			{
				if (gl_ext_pointparameters.value_Renamed != 0.0f)
				{
					//			 qglPointParameterfEXT = ( void (APIENTRY *)( GLenum, GLfloat ) ) qwglGetProcAddress( "glPointParameterfEXT" );
					qglPointParameterfEXT = true;
					//			 qglPointParameterfvEXT = ( void (APIENTRY *)( GLenum, const GLfloat * ) ) qwglGetProcAddress( "glPointParameterfvEXT" );
					VID.Printf(Defines.PRINT_ALL, "...using GL_EXT_point_parameters\n");
				}
				else
				{
					VID.Printf(Defines.PRINT_ALL, "...ignoring GL_EXT_point_parameters\n");
				}
			}
			else
			{
				VID.Printf(Defines.PRINT_ALL, "...GL_EXT_point_parameters not found\n");
			}
			
			// #ifdef __linux__
			//	 if ( strstr( gl_config.extensions_string, "3DFX_set_global_palette" ))
			//	 {
			//		 if ( gl_ext_palettedtexture->value )
			//		 {
			//			 VID.Printf( Defines.PRINT_ALL, "...using 3DFX_set_global_palette\n" );
			//			 qgl3DfxSetPaletteEXT = ( void ( APIENTRY * ) (GLuint *) )qwglGetProcAddress( "gl3DfxSetPaletteEXT" );
			////			 qglColorTableEXT = Fake_glColorTableEXT;
			//		 }
			//		 else
			//		 {
			//			 VID.Printf( Defines.PRINT_ALL, "...ignoring 3DFX_set_global_palette\n" );
			//		 }
			//	 }
			//	 else
			//	 {
			//		 VID.Printf( Defines.PRINT_ALL, "...3DFX_set_global_palette not found\n" );
			//	 }
			// #endif
			
			if (!qglColorTableEXT && gl_config.extensions_string.IndexOf("GL_EXT_paletted_texture") >= 0 && gl_config.extensions_string.IndexOf("GL_EXT_shared_texture_palette") >= 0)
			{
				if (gl_ext_palettedtexture.value_Renamed != 0.0f)
				{
					VID.Printf(Defines.PRINT_ALL, "...using GL_EXT_shared_texture_palette\n");
					qglColorTableEXT = false; // true; TODO jogl bug
				}
				else
				{
					VID.Printf(Defines.PRINT_ALL, "...ignoring GL_EXT_shared_texture_palette\n");
					qglColorTableEXT = false;
				}
			}
			else
			{
				VID.Printf(Defines.PRINT_ALL, "...GL_EXT_shared_texture_palette not found\n");
			}
			
			if (gl_config.extensions_string.IndexOf("GL_ARB_multitexture") >= 0)
			{
				VID.Printf(Defines.PRINT_ALL, "...using GL_ARB_multitexture\n");
				qglActiveTextureARB = true;
				GL_TEXTURE0 = ARBMultitexture.GL_TEXTURE0_ARB;
				GL_TEXTURE1 = ARBMultitexture.GL_TEXTURE1_ARB;
			}
			else
			{
				VID.Printf(Defines.PRINT_ALL, "...GL_ARB_multitexture not found\n");
			}
			
			if (!(qglActiveTextureARB))
				return false;
			
			GL_SetDefaultState();
			
			GL_InitImages();
			Mod_Init();
			R_InitParticleTexture();
			Draw_InitLocal();
			
			int err = gl.glGetError();
			if (err != GL11.GL_NO_ERROR)
				VID.Printf(Defines.PRINT_ALL, "glGetError() = 0x%x\n\t%s\n", new Vargs(2).add(err).add("" + gl.glGetString(err)));
			
			return true;
		}
		
		/// <summary> R_Shutdown</summary>
		protected internal virtual void  R_Shutdown()
		{
			Cmd.RemoveCommand("modellist");
			Cmd.RemoveCommand("screenshot");
			Cmd.RemoveCommand("imagelist");
			Cmd.RemoveCommand("gl_strings");
			
			Mod_FreeAll();
			
			GL_ShutdownImages();
			
			/*
			* shut down OS specific OpenGL stuff like contexts, etc.
			*/
			GLimp_Shutdown();
		}
		
		/// <summary> R_BeginFrame</summary>
		protected internal virtual void  R_BeginFrame(float camera_separation)
		{
			
			gl_state.camera_separation = camera_separation;
			
			/*
			** change modes if necessary
			*/
			if (gl_mode.modified || vid_fullscreen.modified)
			{
				// FIXME: only restart if CDS is required
				cvar_t ref_Renamed;
				
				ref_Renamed = Cvar.Get("vid_ref", "lwjgl", 0);
				ref_Renamed.modified = true;
			}
			
			if (gl_log.modified)
			{
				GLimp_EnableLogging((gl_log.value_Renamed != 0.0f));
				gl_log.modified = false;
			}
			
			if (gl_log.value_Renamed != 0.0f)
			{
				GLimp_LogNewFrame();
			}
			
			/*
			** update 3Dfx gamma -- it is expected that a user will do a vid_restart
			** after tweaking this value
			*/
			if (vid_gamma.modified)
			{
				vid_gamma.modified = false;
				
				if ((gl_config.renderer & GL_RENDERER_VOODOO) != 0)
				{
					// wird erstmal nicht gebraucht
					
					/* 
					char envbuffer[1024];
					float g;
					
					g = 2.00 * ( 0.8 - ( vid_gamma->value - 0.5 ) ) + 1.0F;
					Com_sprintf( envbuffer, sizeof(envbuffer), "SSTV2_GAMMA=%f", g );
					putenv( envbuffer );
					Com_sprintf( envbuffer, sizeof(envbuffer), "SST_GAMMA=%f", g );
					putenv( envbuffer );
					*/
					VID.Printf(Defines.PRINT_DEVELOPER, "gamma anpassung fuer VOODOO nicht gesetzt");
				}
			}
			
			GLimp_BeginFrame(camera_separation);
			
			/*
			** go into 2D mode
			*/
			gl.glViewport(0, 0, vid.width, vid.height);
			gl.glMatrixMode(GL11.GL_PROJECTION);
			gl.glLoadIdentity();
			gl.glOrtho(0, vid.width, vid.height, 0, - 99999, 99999);
			gl.glMatrixMode(GL11.GL_MODELVIEW);
			gl.glLoadIdentity();
			gl.glDisable(GL11.GL_DEPTH_TEST);
			gl.glDisable(GL11.GL_CULL_FACE);
			gl.glDisable(GL11.GL_BLEND);
			gl.glEnable(GL11.GL_ALPHA_TEST);
			gl.glColor4f(1, 1, 1, 1);
			
			/*
			** draw buffer stuff
			*/
			if (gl_drawbuffer.modified)
			{
				gl_drawbuffer.modified = false;
				
				if (gl_state.camera_separation == 0 || !gl_state.stereo_enabled)
				{
					if (gl_drawbuffer.string_Renamed.ToUpper().Equals("GL_FRONT".ToUpper()))
						gl.glDrawBuffer(GL11.GL_FRONT);
					else
						gl.glDrawBuffer(GL11.GL_BACK);
				}
			}
			
			/*
			** texturemode stuff
			*/
			if (gl_texturemode.modified)
			{
				GL_TextureMode(gl_texturemode.string_Renamed);
				gl_texturemode.modified = false;
			}
			
			if (gl_texturealphamode.modified)
			{
				GL_TextureAlphaMode(gl_texturealphamode.string_Renamed);
				gl_texturealphamode.modified = false;
			}
			
			if (gl_texturesolidmode.modified)
			{
				GL_TextureSolidMode(gl_texturesolidmode.string_Renamed);
				gl_texturesolidmode.modified = false;
			}
			
			/*
			** swapinterval stuff
			*/
			GL_UpdateSwapInterval();
			
			//
			// clear screen if desired
			//
			R_Clear();
		}
		
		internal int[] r_rawpalette = new int[256];
		
		/// <summary> R_SetPalette</summary>
		protected internal virtual void  R_SetPalette(sbyte[] palette)
		{
			// 256 RGB values (768 bytes)
			// or null
			int i;
			int color = 0;
			
			if (palette != null)
			{
				int j = 0;
				for (i = 0; i < 256; i++)
				{
					color = (palette[j++] & 0xFF) << 0;
					color |= (palette[j++] & 0xFF) << 8;
					color |= (palette[j++] & 0xFF) << 16;
					color |= unchecked((int) 0xFF000000);
					r_rawpalette[i] = color;
				}
			}
			else
			{
				for (i = 0; i < 256; i++)
				{
					r_rawpalette[i] = d_8to24table[i] | unchecked((int) 0xff000000);
				}
			}
			GL_SetTexturePalette(r_rawpalette);
			
			gl.glClearColor(0, 0, 0, 0);
			gl.glClear(GL11.GL_COLOR_BUFFER_BIT);
			gl.glClearColor(1f, 0f, 0.5f, 0.5f);
		}
		
		internal const int NUM_BEAM_SEGS = 6;
		internal float[][] start_points = new float[NUM_BEAM_SEGS][];
		// array of vec3_t
		internal float[][] end_points = new float[NUM_BEAM_SEGS][]; // array of vec3_t
		
		// stack variable
		//UPGRADE_NOTE: Final was removed from the declaration of 'perpvec '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
		private float[] perpvec = new float[]{0, 0, 0}; // vec3_t
		//UPGRADE_NOTE: Final was removed from the declaration of 'direction '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
		private float[] direction = new float[]{0, 0, 0}; // vec3_t
		//UPGRADE_NOTE: Final was removed from the declaration of 'normalized_direction '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
		private float[] normalized_direction = new float[]{0, 0, 0}; // vec3_t
		//UPGRADE_NOTE: Final was removed from the declaration of 'oldorigin '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
		private float[] oldorigin = new float[]{0, 0, 0}; // vec3_t
		//UPGRADE_NOTE: Final was removed from the declaration of 'origin '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
		private float[] origin = new float[]{0, 0, 0}; // vec3_t
		/// <summary> R_DrawBeam</summary>
		internal virtual void  R_DrawBeam(entity_t e)
		{
			oldorigin[0] = e.oldorigin[0];
			oldorigin[1] = e.oldorigin[1];
			oldorigin[2] = e.oldorigin[2];
			
			origin[0] = e.origin[0];
			origin[1] = e.origin[1];
			origin[2] = e.origin[2];
			
			normalized_direction[0] = direction[0] = oldorigin[0] - origin[0];
			normalized_direction[1] = direction[1] = oldorigin[1] - origin[1];
			normalized_direction[2] = direction[2] = oldorigin[2] - origin[2];
			
			if (Math3D.VectorNormalize(normalized_direction) == 0.0f)
				return ;
			
			Math3D.PerpendicularVector(perpvec, normalized_direction);
			Math3D.VectorScale(perpvec, e.frame / 2, perpvec);
			
			for (int i = 0; i < 6; i++)
			{
				Math3D.RotatePointAroundVector(start_points[i], normalized_direction, perpvec, (360.0f / NUM_BEAM_SEGS) * i);
				
				Math3D.VectorAdd(start_points[i], origin, start_points[i]);
				Math3D.VectorAdd(start_points[i], direction, end_points[i]);
			}
			
			gl.glDisable(GL11.GL_TEXTURE_2D);
			gl.glEnable(GL11.GL_BLEND);
			gl.glDepthMask(false);
			
			float r = (d_8to24table[e.skinnum & 0xFF]) & 0xFF;
			float g = (d_8to24table[e.skinnum & 0xFF] >> 8) & 0xFF;
			float b = (d_8to24table[e.skinnum & 0xFF] >> 16) & 0xFF;
			
			r *= 1 / 255.0f;
			g *= 1 / 255.0f;
			b *= 1 / 255.0f;
			
			gl.glColor4f(r, g, b, e.alpha);
			
			gl.glBegin(GL11.GL_TRIANGLE_STRIP);
			
			float[] v;
			
			for (int i = 0; i < NUM_BEAM_SEGS; i++)
			{
				v = start_points[i];
				gl.glVertex3f(v[0], v[1], v[2]);
				v = end_points[i];
				gl.glVertex3f(v[0], v[1], v[2]);
				v = start_points[(i + 1) % NUM_BEAM_SEGS];
				gl.glVertex3f(v[0], v[1], v[2]);
				v = end_points[(i + 1) % NUM_BEAM_SEGS];
				gl.glVertex3f(v[0], v[1], v[2]);
			}
			gl.glEnd();
			
			gl.glEnable(GL11.GL_TEXTURE_2D);
			gl.glDisable(GL11.GL_BLEND);
			gl.glDepthMask(true);
		}
	}
}